import javafx.geometry.Insets;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;


import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class GameBoard {
    private final int width;
    private final int height;
    private final int level;
    private final GridPane boardPane;
    private final Cell[][] cells;
    private final Random random = new Random();
    private static final int COLOR_COUNT = 5; // 游戏元素的颜色种类
    public GameBoard(int width, int height, int level) {
        this.width = width;
        this.height = height;
        this.level = level;
        this.boardPane = new GridPane();
        this.cells = new Cell[width][height];

        initializeBoard();
    }

    public List<Match> findMatches() {
        List<Match> matches = new ArrayList<>();

        // 水平检测
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width - 2; x++) {
                if (cells[x][y].getColor() != null &&
                        cells[x][y].getColor().equals(cells[x+1][y].getColor()) &&
                        cells[x][y].getColor().equals(cells[x+2][y].getColor())) {

                    List<Cell> matchCells = new ArrayList<>();
                    int endX = x;
                    while (endX < width &&
                            cells[endX][y].getColor() != null &&
                            cells[endX][y].getColor().equals(cells[x][y].getColor())) {
                        matchCells.add(cells[endX][y]);
                        cells[endX][y].setMatched(true);
                        endX++;
                    }

                    if (matchCells.size() >= 3) {
                        matches.add(new Match(matchCells));
                    }
                }
            }
        }

        // 垂直检测
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height - 2; y++) {
                if (cells[x][y].getColor() != null &&
                        cells[x][y].getColor().equals(cells[x][y+1].getColor()) &&
                        cells[x][y].getColor().equals(cells[x][y+2].getColor())) {

                    List<Cell> matchCells = new ArrayList<>();
                    int endY = y;
                    while (endY < height &&
                            cells[x][endY].getColor() != null &&
                            cells[x][endY].getColor().equals(cells[x][y].getColor())) {
                        matchCells.add(cells[x][endY]);
                        cells[x][endY].setMatched(true);
                        endY++;
                    }

                    if (matchCells.size() >= 3) {
                        matches.add(new Match(matchCells));
                    }
                }
            }
        }

        return matches;
    }
    public int clearMatches() {
        int clearedCount = 0;
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                if (cells[x][y].isMatched()) {
                    cells[x][y].setColor(null);
                    cells[x][y].setMatched(false);
                    cells[x][y].updateAppearance(); // 更新UI
                    clearedCount++;
                }
            }
        }
        return clearedCount;
    }
    private void initializeBoard() {
        boardPane.setPadding(new Insets(10));
        boardPane.setHgap(5);
        boardPane.setVgap(5);

        // 初始化棋盘单元格
        for (int row = 0; row < width; row++) {
            for (int col = 0; col < height; col++) {
                Cell cell = new Cell(row, col, getRandomColor());
                cells[row][col] = cell;
                boardPane.add(cell.getCellPane(), col, row);
            }
        }

        // 确保初始棋盘没有可消除的组合
        while (hasMatches()) {
            clearMatches();
            fillEmptyCells();
        }
    }
    private String getRandomColor() {
        int colorIndex = random.nextInt(COLOR_COUNT);
        switch (colorIndex) {
            case 0: return "RED";
            case 1: return "BLUE";
            case 2: return "GREEN";
            case 3: return "YELLOW";
            case 4: return "PURPLE";
            default: return "BLACK";
        }
    }
    public boolean swapCells(int x1, int y1, int x2, int y2) {
        if (!isAdjacent(x1, y1, x2, y2)) {
            return false;
        }
        Cell cell1 = cells[x1][y1];
        Cell cell2 = cells[x2][y2];

        // 交换颜色
        String tempColor = cell1.getColor();
        cell1.setColor(cell2.getColor());
        cell2.setColor(tempColor);

        // 更新UI
        cell1.updateAppearance();
        cell2.updateAppearance();

        return true;
    }
    private boolean isAdjacent(int x1, int y1, int x2, int y2) {
        int dx = Math.abs(x1 - x2);
        int dy = Math.abs(y1 - y2);
        return (dx == 1 && dy == 0) || (dx == 0 && dy == 1);
    }
    public boolean hasMatches() {
        return !findMatches().isEmpty();
    }
    public void fillEmptyCells() {
        // 让方块下落
        for (int x = 0; x < width; x++) {
            int emptyY = height - 1;

            for (int y = height - 1; y >= 0; y--) {
                if (cells[x][y].getColor() == null) {
                    // 寻找上方第一个有颜色的方块
                    for (int above = y - 1; above >= 0; above--) {
                        if (cells[x][above].getColor() != null) {
                            // 移动方块
                            cells[x][y].setColor(cells[x][above].getColor());
                            cells[x][above].setColor(null);
                            cells[x][y].updateAppearance();
                            cells[x][above].updateAppearance();
                            break;
                        }
                    }
                }
            }

            // 填充顶部空白
            for (int y = 0; y < height; y++) {
                if (cells[x][y].getColor() == null) {
                    cells[x][y].setColor(getRandomColor());
                    cells[x][y].updateAppearance();
                }
            }
        }
    }
    public Cell getCell(int x, int y) {
        if (x >= 0 && x < width && y >= 0 && y < height) {
            return cells[x][y];
        }
        return null;
    }
    public GridPane getBoardPane() {
        return boardPane;
    }
    public StackPane getCellAt(int x, int y) {
        if (x >= 0 && x < width && y >= 0 && y < height) {
            return cells[x][y];
        }
        return null;
    }
    public int getWidth() {
        return width;
    }
    public int getHeight() {
        return height;
    }
    public static class Match {
        private final List<Cell> cells;

        public Match(List<Cell> cells) {
            this.cells = cells;
        }

        public List<Cell> getCells() {
            return cells;
        }

        public int getLength() {
            return cells.size();
        }
    }
}
